package com.bestcem.xm.ticket.dao.impl.mysql;

import cn.hutool.core.lang.ObjectId;
import com.alibaba.fastjson.JSON;
import com.bestcem.xm.common.core.uitls.DateUtil;
import com.bestcem.xm.ticket.controller.param.PageParam;
import com.bestcem.xm.ticket.dao.*;
import com.bestcem.xm.ticket.dao.converter.TicketConfigConverter;
import com.bestcem.xm.ticket.dao.dto.TicketConfigInfo;
import com.bestcem.xm.ticket.dao.dto.TicketConfigV3Info;
import com.bestcem.xm.ticket.dao.mapper.TicketConfigDaoMapper;
import com.bestcem.xm.ticket.entity.mongo.*;
import com.bestcem.xm.ticket.entity.mysql.TicketConfigDO;
import com.bestcem.xm.ticket.enums.TemplateTypeEnum;
import com.bestcem.xm.ticket.enums.TicketConfigStateEnum;
import com.bestcem.xm.ticket.service.dto.PageDTO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Repository;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author zhangfeng <feng.zhang@idiaoyan.com>
 * @version v1.0
 * @date 2021/9/18 14:30
 */
@Slf4j
@Repository
public class TicketConfigDaoImpl implements TicketConfigDao {
    @Resource
    private TicketConfigDaoMapper ticketConfigDaoMapper;
    @Resource
    private TicketFlowDao ticketFlowDao;
    @Resource
    private TicketNotifyConfigDao ticketNotifyConfigDao;
    @Resource
    private TicketRuleDao ticketRuleDao;
    @Resource
    private TemplateDao templateDao;

    @Override
    public TicketConfig findById(String id) {
        TicketConfigDO ticketConfigDO = ticketConfigDaoMapper.findByTicketConfigId(id);

        return TicketConfigConverter.doToDto(ticketConfigDO);
    }

    @Override
    public TicketConfig findByTitle(String title) {
        TicketConfigDO ticketConfigDO = ticketConfigDaoMapper.findByTitle(title);

        return TicketConfigConverter.doToDto(ticketConfigDO);
    }

    @Override
    public TicketConfig findBySurveyIdAndTitle(String surveyId, String title) {
        TicketConfigDO ticketConfigDO = ticketConfigDaoMapper.findBySurveyIdAndTitle(surveyId, title);

        return TicketConfigConverter.doToDto(ticketConfigDO);
    }

    @Override
    public List<TicketConfig> listByOrgId(String orgId) {
        List<TicketConfigDO> ticketConfigDOList = ticketConfigDaoMapper.listByOrgId(orgId);

        return TicketConfigConverter.doListToDtoList(ticketConfigDOList);
    }

    @Override
    public List<TicketConfig> listByOrgIdEnable(String orgId) {
        List<TicketConfigDO> ticketConfigDOS = ticketConfigDaoMapper.listByOrgIdEnable(orgId, TicketConfigStateEnum.DELETE.getIndex());
        return TicketConfigConverter.doListToDtoList(ticketConfigDOS);
    }

    @Override
    public PageDTO<TicketConfig> listByOrgId(String orgId, PageParam pageParam) {
        // 查询总数
        long total = ticketConfigDaoMapper.countByOrgIdAndTicketRuleId(orgId);
        if (total == 0) {
            return new PageDTO<>(pageParam.getPage(), new ArrayList<TicketConfig>(), total);
        }

        // 由于id是objectid，所以使用max函数获取surveyId对应的最大的id分页列表，再通过id去查询title
        int offset = (pageParam.getPage() - 1) * pageParam.getSize();
        List<TicketConfigDO> ticketConfigDOList = ticketConfigDaoMapper.listByOrgIdAndTicketRuleId(orgId, offset, pageParam.getSize());
        if (!CollectionUtils.isEmpty(ticketConfigDOList)) {
            List<String> ids = ticketConfigDOList.stream().map(TicketConfigDO::getTicketConfigId).collect(Collectors.toList());
            List<TicketConfigDO> titleList = ticketConfigDaoMapper.listByTicketConfigIdList(ids);
            Map<String, String> titleMap = titleList.stream().collect(Collectors.toMap(TicketConfigDO::getTicketConfigId, TicketConfigDO::getTitle));
            for (TicketConfigDO ticketConfigDO : ticketConfigDOList) {
                String title = titleMap.get(ticketConfigDO.getTicketConfigId());
                ticketConfigDO.setTitle(title);
            }
        }

        return new PageDTO<>(pageParam.getPage(), TicketConfigConverter.doListToDtoList(ticketConfigDOList), total);
    }

    @Override
    public List<TicketConfig> listBySurveyId(String surveyId, Boolean descByCreatedTime) {
        List<TicketConfigDO> ticketConfigDOList = ticketConfigDaoMapper.listBySurveyId(surveyId, descByCreatedTime);

        return TicketConfigConverter.doListToDtoList(ticketConfigDOList);
    }

    @Override
    public TicketConfig saveTicketConfig(TicketConfig ticketConfig) {
        TicketConfigDO entityDo = TicketConfigConverter.dtoToDo(ticketConfig);
        if (Objects.isNull(entityDo)) {
            return null;
        }

        if (ObjectUtils.isEmpty(entityDo.getTicketConfigId())) {
            entityDo.setTicketConfigId(ObjectId.next());
        }
        if (Objects.isNull(entityDo.getCreateTime())) {
            entityDo.setCreateTime(DateUtil.getCommonDate());
        }
        if (Objects.isNull(entityDo.getUpdateTime())) {
            entityDo.setUpdateTime(DateUtil.getCommonDate());
        }

        ticketConfigDaoMapper.insert(entityDo);

        entityDo = ticketConfigDaoMapper.findByTicketConfigId(entityDo.getTicketConfigId());

        return TicketConfigConverter.doToDto(entityDo);
    }

    @Override
    public List<TicketConfig> listTicketConfig(String orgId, String surveyId, Integer status) {
        List<TicketConfigDO> ticketConfigDOList = ticketConfigDaoMapper.listByOrgIdAndSurveyIdAndState(orgId,
                surveyId, status);

        return TicketConfigConverter.doListToDtoList(ticketConfigDOList);
    }

    @Override
    public List<TicketConfigInfo> listTicketConfigInfo(String id) {
        TicketConfigDO ticketConfigDO = ticketConfigDaoMapper.findByTicketConfigId(id);
        List<TicketConfigInfo> resultList = new ArrayList<>();
        if (Objects.isNull(ticketConfigDO)) {
            return resultList;
        }
        List<TicketFlow> flowList = ticketFlowDao.findByConfigId(id);
        List<TicketNotifyConfig> notifyConfigList = ticketNotifyConfigDao.findAllByTicketConfigId(id);
        List<TicketRule> ruleList = ticketRuleDao.listByTicketConfigId(id);

        TicketConfigInfo ticketConfigInfo = new TicketConfigInfo();
        ticketConfigInfo = TicketConfigConverter.setDto(ticketConfigInfo, ticketConfigDO);
        ticketConfigInfo.setTicketFlow(flowList);
        ticketConfigInfo.setTicketRule(ruleList);
        ticketConfigInfo.setTicketNotifyConfig(notifyConfigList);
        resultList.add(ticketConfigInfo);
        return resultList;
    }

    @Override
    public List<TicketConfigV3Info> listTicketConfigV3Info(String id) {
        TicketConfigDO ticketConfigDO = ticketConfigDaoMapper.findByTicketConfigId(id);

        List<TicketConfigV3Info> resultList = new ArrayList<>();
        if (Objects.isNull(ticketConfigDO)) {
            return resultList;
        }
        List<TicketFlow> flowList = ticketFlowDao.findByConfigId(id);
        List<TicketNotifyConfig> notifyConfigList = ticketNotifyConfigDao.findAllByTicketConfigId(id);
        List<TicketRule> ruleList = ticketRuleDao.listByTicketConfigId(id);
        List<TicketTemplateV2> ticketTemplateV2List = templateDao.listByTicketConfigId(id);

        TicketConfigV3Info ticketConfigV3Info = new TicketConfigV3Info();
        ticketConfigV3Info = TicketConfigConverter.setDto(ticketConfigV3Info, ticketConfigDO);
        ticketConfigV3Info.setTicketFlow(flowList);
        ticketConfigV3Info.setTicketRule(ruleList);
        ticketConfigV3Info.setTicketNotifyConfig(notifyConfigList);
        ticketConfigV3Info.setTicketTemplate(ticketTemplateV2List);
        resultList.add(ticketConfigV3Info);

        return resultList;
    }

    @Override
    public boolean updateTitle(String id, String title) {
        TicketConfigDO entityDo = new TicketConfigDO();
        entityDo.setTicketConfigId(id);
        entityDo.setTitle(title);

        entityDo.setUpdateTime(DateUtil.getCommonDate());
        ticketConfigDaoMapper.updateByTicketConfigId(entityDo);

        return true;
    }

    @Override
    public boolean updateState(String id, TicketConfigStateEnum state) {
        TicketConfigDO entityDo = new TicketConfigDO();
        entityDo.setTicketConfigId(id);
        entityDo.setState(state.getIndex());
        entityDo.setUpdateTime(DateUtil.getCommonDate());

        ticketConfigDaoMapper.updateByTicketConfigId(entityDo);

        return true;
    }

    @Override
    public String updateTicketConfig(String id, TicketConfig entity) {
        if (Objects.isNull(entity)) {
            return null;
        }

        entity.setId(id);
        TicketConfigDO entityDo = TicketConfigConverter.dtoToDo(entity);
        if (Objects.isNull(entityDo)) {
            return null;
        }
        entityDo.setUpdateTime(DateUtil.getCommonDate());

        ticketConfigDaoMapper.updateByTicketConfigId(entityDo);

        return id;
    }

    @Override
    public void updateTicketNotifyConfigIds(String id, List<String> ticketNotifyConfigIds) {
        TicketConfigDO entityDo = new TicketConfigDO();
        entityDo.setTicketConfigId(id);
        entityDo.setTicketNotifyConfigIds(JSON.toJSONString(ticketNotifyConfigIds));

        entityDo.setUpdateTime(DateUtil.getCommonDate());
        ticketConfigDaoMapper.updateByTicketConfigId(entityDo);
    }

    @Override
    public TicketConfig findByTemplateId(String templateId, Integer type) {
        TicketConfigDO ticketConfigDO = null;
        if (TemplateTypeEnum.TEMPLATE_INFO.getIndex().equals(type)) {
            ticketConfigDO = ticketConfigDaoMapper.findByDetailTemplateId(templateId);
        } else if (TemplateTypeEnum.TEMPLATE_HANDLE.getIndex().equals(type)) {
            ticketConfigDO = ticketConfigDaoMapper.findByTicketTemplateId(templateId);
        }

        return TicketConfigConverter.doToDto(ticketConfigDO);
    }

    @Override
    public long countEnabledBySurveyId(String surveyId, String title) {
        return ticketConfigDaoMapper.countBySurveyIdAndTitle(surveyId, title);
    }

    @Override
    public Integer updateDefaultTemplateId(Integer type, String orgId, String templateId, String oldTemplateId) {
        if (StringUtils.isBlank(templateId) || !org.bson.types.ObjectId.isValid(templateId)
                || StringUtils.isBlank(orgId) || !org.bson.types.ObjectId.isValid(orgId)
                || StringUtils.isBlank(oldTemplateId) || !org.bson.types.ObjectId.isValid(oldTemplateId)) {
            log.info("-------参数不合理type:{},orgid:{},templateId{}--", type, orgId, templateId);
            return 0;
        }

        if (TemplateTypeEnum.TEMPLATE_INFO.getIndex().equals(type)) {
            return ticketConfigDaoMapper.updateDetailTemplateId(templateId, oldTemplateId, orgId, DateUtil.getCommonDate());
        } else if (TemplateTypeEnum.TEMPLATE_HANDLE.getIndex().equals(type)) {
            return ticketConfigDaoMapper.updateTicketTemplateId(templateId, oldTemplateId, orgId, DateUtil.getCommonDate());
        } else {
            return 0;
        }
    }

    @Override
    public PageDTO<TicketConfig> pageTicketConfig(String orgId, PageParam pageParam) {
        // 查总数
        Long total = ticketConfigDaoMapper.countByOrgIdAndTicketRuleIdNotNull(orgId);

        // 分页查询设置
        Integer page = pageParam.getPage();
        Integer size = pageParam.getSize();
        // 前端传来的page至少为1,因此这里减去1
        Integer skip = (page - 1) * size;

        // 总数为0时不必再查,直接返回即可
        List<TicketConfig> list = new ArrayList<>();
        if (total == 0) {
            return new PageDTO<>(page, list, total);
        }

        List<TicketConfigDO> doList = ticketConfigDaoMapper.listByOrgIdAndTicketRuleIdNotNull(orgId, skip, size);

        return new PageDTO<>(pageParam.getPage(), TicketConfigConverter.doListToDtoList(doList), total);
    }

    @Override
    public String queTemplateDetailId(String id) {
        TicketConfigDO ticketConfigDO = ticketConfigDaoMapper.findByDetailTemplateId(id);
        if (Objects.nonNull(ticketConfigDO)) {
            return ticketConfigDO.getDetailTemplateId();
        }
        return "";
    }

    @Override
    public String queTemplateHandleId(String id) {
        TicketConfigDO ticketConfigDO = ticketConfigDaoMapper.findByTicketTemplateId(id);
        if (Objects.nonNull(ticketConfigDO)) {
            return ticketConfigDO.getTicketTemplateId();
        }
        return "";
    }

    @Override
    public TicketConfig getRecentUseTemplate(String orgId, String userId) {
        TicketConfigDO ticketConfigDO = ticketConfigDaoMapper.findByOrgIdAndUserId(orgId, userId);

        return TicketConfigConverter.doToDto(ticketConfigDO);
    }

    /**
     * 获取公司下开启所有了工单的问卷id
     *
     * @param orgId 公司id
     * @return 问卷id列表
     * @author XiaoYunSong <ys.xiao@idiaoyan.com>
     * @date 2021/11/9 11:27
     */
    @Override
    public LinkedHashSet<String> groupSurveyId(String orgId) {
        return ticketConfigDaoMapper.groupSurveyId(orgId);
    }

    /**
     * 批量查询 TicketConfig
     *
     * @param ids id list
     * @return TicketConfig 列表
     * @author XiaoYunSong <ys.xiao@idiaoyan.com>
     * @date 2021/11/16 15:39
     */
    @Override
    public List<TicketConfig> listByIds(Collection<String> ids) {
        List<TicketConfigDO> doList = ticketConfigDaoMapper.listByTicketConfigIdList(new ArrayList<>(ids));
        return TicketConfigConverter.doListToDtoList(doList);
    }

    @Override
    public List<String> listEnabledBySurveyId(String surveyId) {
        return ticketConfigDaoMapper.listEnabledBySurveyId(surveyId);
    }

    /**
     * 搜索并分页查询 TicketConfig
     *
     * @param orgId     租户id
     * @param search    搜索关键词
     * @param pageParam 分页参数
     * @return 搜索分页结果
     * @author XiaoYunSong <ys.xiao@idiaoyan.com>
     * @date 2021/12/17 17:28
     */
    @Override
    public PageDTO<TicketConfig> searchAndPage(String orgId, String search, PageParam pageParam) {
        long total = ticketConfigDaoMapper.countByOrgIdAndSearch(orgId, search);
        // 总数为0时不必再查,直接返回即可
        if (total == 0) {
            return new PageDTO<>(pageParam.getPage(), new ArrayList<>(), total);
        }
        if (Objects.isNull(pageParam)) {
            pageParam = new PageParam(0, 10);
        }
        List<TicketConfigDO> ticketConfigDOS = ticketConfigDaoMapper.pageByOrgIdAndSearch(orgId, search,
                pageParam.getPage() * pageParam.getSize(), pageParam.getSize());
        List<TicketConfig> list = TicketConfigConverter.doListToDtoList(ticketConfigDOS);
        return new PageDTO<>(pageParam.getPage(), list, total);
    }

    /**
     * 根据工单规则名称关键词搜索工单规则
     *
     * @param orgId  租户id
     * @param search 搜索关键词
     * @return 工单id
     * @author XiaoYunSong <ys.xiao@idiaoyan.com>
     * @date 2021/12/17 17:28
     */
    @Override
    public List<String> searchTicketConfigId(String orgId, String search) {
        List<TicketConfigDO> ticketConfigDOS = ticketConfigDaoMapper.listByOrgIdAndSearch(orgId, search);
        List<String> result = new ArrayList<>();
        if (!CollectionUtils.isEmpty(ticketConfigDOS)) {
            for (TicketConfigDO ticketConfig : ticketConfigDOS) {
                if (ObjectId.isValid(ticketConfig.getTicketConfigId())) {
                    result.add(ticketConfig.getTicketConfigId());
                }
            }
        }
        return result;
    }
}
